//
//  HPopupView.m
//  popview
//
//  Created by 王 文彬 on 13-11-2.
//  Copyright (c) 2013年 重庆芬尼尔科技发展有限公司. All rights reserved.
//

#import "HPopupView.h"
#import <QuartzCore/QuartzCore.h>



#pragma mark - HPopupBackgroundWindow 定义半透明窗口
@interface HPopupBackgroundWindow : UIWindow

@property (nonatomic, assign) BOOL isTransparent;

@end


@implementation HPopupBackgroundWindow

@synthesize isTransparent;


- (void)drawRect:(CGRect)rect
{
    if (!self.isTransparent) {
        
        CGContextRef context = UIGraphicsGetCurrentContext();
        
        size_t num_locations = 2;
        CGFloat locations[2] = { 0.0, 1.0 };
        CGFloat components[8] = { 0.0, 0.0, 0.0, 0.4, // Start color
            
            0.0, 0.0, 0.0, 0.4
        }; // End color
        
        CGColorSpaceRef rgbColorspace = CGColorSpaceCreateDeviceRGB();
        CGGradientRef backgroundGradient = CGGradientCreateWithColorComponents (rgbColorspace, components, locations, num_locations);
        //从中心点画原型辐射状
        CGPoint centerPoint = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
        CGContextDrawRadialGradient (context, backgroundGradient, centerPoint, 0.0, centerPoint, self.bounds.size.width, kCGGradientDrawsAfterEndLocation);
        //从左上到右下画
//        CGContextDrawLinearGradient(context, backgroundGradient, CGPointMake(0, 0), CGPointMake(self.frame.size.width, self.frame.size.height), kCGGradientDrawsBeforeStartLocation);
        CGGradientRelease(backgroundGradient);
    }
}

@end


//////////////////////////////////////////////////////

#pragma mark - HPopupView
@interface HPopupView ()

@property (nonatomic, strong) UIButton* cancelButton;

- (UIButton *)otherButtonWithIndex:(NSInteger)index;

@end


@implementation HPopupView
{
    UIWindow*    _oldKeyWindow;
    HPopupBackgroundWindow* _keyWindow;
    
    BOOL         _isAutoCenter;  //是否自动居中。当从init创建实例就=true，从initWithFrame创建实例=false
    
    UILabel*     _titleLabel;
    UILabel*     _contentLabel;
    
    UIButton*    _cancelButton;
    NSMutableArray* _otherButtons;
    
    UIView*      _buttonsContainer;
    
    
}

@synthesize cancelButton = _cancelButton;

- (id)init
{
    float x = 30;
    float width = [UIScreen mainScreen].bounds.size.width - x * 2;
    
    float height = 200;
    float y = ( [UIScreen mainScreen].bounds.size.height - height ) / 2;
    
    self = [super initWithFrame:CGRectMake(x, y, width, height)];
    if (self) {
        
        _isAutoCenter = true;
        [self initComponents];
    }
    return self;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {

        _isAutoCenter = false;
        [self initComponents];
    }
    return self;
}

- (void)initComponents
{
    self.animationTime = 0.2;
    
    self.backgroundColor = [UIColor whiteColor];
    self.layer.shadowOffset = CGSizeMake(5, 3);
    self.layer.shadowOpacity = 0.6;
    self.layer.shadowColor = [UIColor blackColor].CGColor;
    self.layer.cornerRadius = 3;
    
    //标题
    _titleLabel = [[UILabel alloc] init];
    _titleLabel.textAlignment = NSTextAlignmentCenter;
    _titleLabel.textColor = [UIColor blackColor];
    _titleLabel.font = [UIFont boldSystemFontOfSize:19];
    _titleLabel.backgroundColor = [UIColor clearColor];
    
    //内容
    _contentLabel = [[UILabel alloc] init];
    _contentLabel.font = [UIFont systemFontOfSize:15];
    _contentLabel.textColor = [UIColor grayColor];
    _contentLabel.textAlignment = NSTextAlignmentCenter;
    _contentLabel.lineBreakMode = UILineBreakModeWordWrap;
    _contentLabel.numberOfLines = 100;
    _contentLabel.backgroundColor = [UIColor clearColor];
    
    //按钮的容器
    _buttonsContainer = [[UIView alloc] init];
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code
}
*/

#pragma mark - 设置Block
- (void)setWillShowBlock:(HPopupViewWillShowBlock)block
{
    _willShowBlock = block;
}

- (void)setButtonClickedBlock:(HPopupViewButtonClickedBlock)block
{
    _buttonClickedBlock = block;
}

#pragma mark - 设置Title
- (void)setTitleFont:(UIFont *)titleFont
{
    _titleLabel.font = titleFont;
}

- (void)setTitleText:(NSString *)titleText
{
    _titleLabel.text = titleText;
}

#pragma mark - 设置文字内容
- (void)setContentFont:(UIFont *)contentFont
{
    _contentLabel.font = contentFont;
}

- (void)setContentText:(NSString *)contentText
{
    _contentLabel.text = contentText;
}

#pragma mark - CancelButton
- (UIButton *)cancelButton
{
    if (_cancelButton == nil) {
        
        _cancelButton = [[UIButton alloc] init];
        _cancelButton.tag = 100 + 0;  //cancelButton永远是第0个
        _cancelButton.layer.cornerRadius = 3;
//        _cancelButton.layer.borderWidth = 1;
//        _cancelButton.layer.borderColor = [[UIColor colorWithRed:215/255.0 green:215/255.0 blue:215/255.0 alpha:1] CGColor];
        _cancelButton.backgroundColor = [UIColor colorWithRed:134/255.0 green:178/255.0 blue:213/255.0 alpha:1];
        [_cancelButton addTarget:self action:@selector(buttonEvent:) forControlEvents:UIControlEventTouchUpInside];
        [_cancelButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    }
    
    return _cancelButton;
}

- (void)setCancelButtonTitle:(NSString *)cancelButtonTitle
{
    if (cancelButtonTitle == nil) {
        
        _cancelButton = nil;
    }
    else {
        
        [self.cancelButton setTitle:cancelButtonTitle forState:UIControlStateNormal];
    }
}

- (NSString *)cancelButtonTitle
{
    return self.cancelButton.titleLabel.text;
}


#pragma mark - 其他按钮
- (void)addButtonTitlt:(NSString *)title
{
    if (_otherButtons == nil) {
        
        _otherButtons = [[NSMutableArray alloc] init];
    }
    
    UIButton* button = [[UIButton alloc] init];
    button.layer.cornerRadius = 3;
//    button.layer.borderWidth = 1;
//    button.layer.borderColor = [[UIColor colorWithRed:235/255.0 green:235/255.0 blue:235/255.0 alpha:1] CGColor];
    button.tag = 101 + _otherButtons.count;   //用下标来做tag，tag用于点击按钮后，识别哪一个被点击，并传给句柄。otherButton永远是从1（即101）开始
    button.backgroundColor = [UIColor colorWithRed:134/255.0 green:213/255.0 blue:199/255.0 alpha:1];
    [button addTarget:self action:@selector(buttonEvent:) forControlEvents:UIControlEventTouchUpInside];
    [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [button setTitle:title forState:UIControlStateNormal];
    [_otherButtons addObject:button];
}

- (UIButton *)otherButtonWithIndex:(NSInteger)index
{
    if (_otherButtons != nil && _otherButtons.count >= index) {
        
        return _otherButtons[index];
    }
    
    return nil;
}

- (void)buttonEvent:(UIButton *)button
{
    int tag = button.tag - 100;

    //调用block，通知句柄拥有者
    if (_buttonClickedBlock) {

        BOOL result = _buttonClickedBlock(self, tag);
        
        //如果执行结果为假，则阻止后面的代码执行，即：让窗口停留
        if (result == false) {

            return;
        }
    }
    
    //主线程中消除遮罩
    dispatch_async(dispatch_get_main_queue(), ^{
        
        [UIView animateWithDuration:self.animationTime animations:^{
            
            _keyWindow.alpha = 0;
        } completion:^(BOOL finished) {
            
            [self close];
        }];
    });
    
    //同时消除视图
    if (_animation == HPopupViewAnimationFade) {
        
        [UIView animateWithDuration:self.animationTime animations:^{
            
            self.transform = CGAffineTransformMakeScale(0.9, 0.9);
            self.alpha = 0;
        }completion:^(BOOL finished) {
            
            [self removeFromSuperview];
        }];
    }
    else if (_animation == HPopupViewAnimationSlideLeftToRight) {
        
        [UIView animateWithDuration:self.animationTime animations:^{

            CGRect newFrame = self.frame;
            newFrame.origin.x = [UIScreen mainScreen].bounds.size.width - newFrame.origin.x;
            self.frame = newFrame;
        }];
    }
    
}

- (void)close
{
    [self removeFromSuperview];    //将自己从窗口移除
    
    [_oldKeyWindow makeKeyAndVisible];   //恢复之前的keyWindow
    
    _keyWindow = nil;  //将窗口设为nil，这时窗口失去拥有者，生命周期结束
}

#pragma mark - 显示视图
- (void)show
{
    _oldKeyWindow = [UIApplication sharedApplication].keyWindow;
    
    _keyWindow = [[HPopupBackgroundWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    _keyWindow.windowLevel = UIWindowLevelStatusBar + 1;
    _keyWindow.backgroundColor = [UIColor clearColor];   //不能是全黑，不然会遮住窗口的半透明效果
    _keyWindow.alpha = 1;
    _keyWindow.isTransparent = self.isTransparent;
    [_keyWindow makeKeyAndVisible];

    [self willShow];   //刷新视图元素，重新计算高度
    
    if (_isAutoCenter) {
        
        self.center = _keyWindow.center;
    }
    [_keyWindow addSubview:self];

    //显示背景遮罩
    //异步的在主线程中显示遮罩，这样不会引起视图动画效果的延迟
//    dispatch_async(dispatch_get_main_queue(), ^{
//        
//        [UIView animateWithDuration:self.animationTime animations:^{
//            
//            _keyWindow.alpha = 1;
//        }];
//    });

    
    //显示视图动画
    if (_animation == HPopupViewAnimationFade) {

        self.alpha = 0.8;
        self.transform = CGAffineTransformMakeScale(0.95, 0.95);
        
        [UIView animateWithDuration:self.animationTime animations:^{
            
            self.transform = CGAffineTransformIdentity;
            self.alpha = 1.0f;
        }];
    }
    else if (_animation == HPopupViewAnimationSlideLeftToRight) {
        
        [UIView animateWithDuration:self.animationTime animations:^{
            
            CGRect origin = self.frame;   //记录下原始frame
            CGRect outOfViewFrame = self.frame;   //出现前的frame
            outOfViewFrame.origin.x = origin.origin.x - origin.origin.x - origin.size.width;   //计算要移动多少，才能把视图移到屏幕外面
            self.frame = outOfViewFrame;    //设定到屏幕外面去
            
            self.frame = origin;
        }];
    }
}

// 刷新视图子元素，并重新计算各元素的位置，和self.frame
// 视图固定子元素为：（N=通过_willShowBlock()加入的子元素个数）
// 1、title：位于第1个子元素，如果没有文字，高度为0；有文字，以字体计算高度。
// 2、content：位于第2个子元素，如果没有文字，高度为0；有文字，以字体计算高度 + 偏移高度+5。
// 3、buttonsContainer：按钮组容器，位于第N+3个子元素，没有子元素，高度为0；有元素，就为元素之和的高度
- (void)willShow
{
    //首先移除所有子元素
    for (UIView* view in self.subviews) {
        
        [view removeFromSuperview];
    }
    
    //同时也移除按钮容器中的所有子元素
    for (UIView* view in _buttonsContainer.subviews) {
        
        [view removeFromSuperview];
    }
    
    
    float gap = 10;   //四边缝隙宽度
    float subViewWidth = self.frame.size.width - gap * 2;   //子视图的最大宽度：本view的宽度 - 左右gap
    
    //标题
    CGSize size = [_titleLabel.text sizeWithFont:_titleLabel.font constrainedToSize:CGSizeMake(subViewWidth, 40) lineBreakMode:UILineBreakModeWordWrap];
    _titleLabel.frame = CGRectMake(gap, gap + 5, subViewWidth, size.height);
    [self addSubview:_titleLabel];

    //内容。内容要接在标题的坐标后面
    size = [_contentLabel.text sizeWithFont:_contentLabel.font constrainedToSize:CGSizeMake(subViewWidth, self.frame.size.height) lineBreakMode:UILineBreakModeWordWrap];
    _contentLabel.frame = CGRectMake(gap, _titleLabel.frame.origin.y + _titleLabel.frame.size.height + gap, subViewWidth, size.height);
    [self addSubview:_contentLabel];
    
    /*
     添加完title和content后，再调用block，使外部可以先改变self的子元素，或加入指定行为
     这样的好处是可以使外部进来的元素覆盖前面的
     */
    if (_willShowBlock) {
        
        _willShowBlock(self);
    }
    

    //先根据目前self中的子视图，计算最大视图高度。
    float maxHeight = 0;
    
    for (UIView* view in self.subviews) {

        float height = view.frame.origin.y + view.frame.size.height;
        
        maxHeight = height > maxHeight ? height : maxHeight;
    }//现在得到的最大高度，并不是真实最大高度，而是要在后面，加上按钮容器高度后的，才是最大高度
    
    
    //按钮容器：把按钮全部放到一个容器里面，整体追加到最后方便计算视图
    _buttonsContainer.frame = CGRectMake(gap, maxHeight, subViewWidth, 0);  //位置紧接y最大的元素，高度回0。一定要重置这个容器的frame，不然可能会由于上次的frame高度，导致后面计算子元素最大高度出错
    [self addSubview:_buttonsContainer];
    
    //装入按钮
    [self assembleButtonsIntoContainerView];

    //最终最大高度
    maxHeight += _buttonsContainer.frame.size.height;
    
    //最大高度 + 上 + 下 * 2
    maxHeight += gap * 3;
    
    //重新调整视图：如果最大高度大于设定的frame高度，才调整；小于则不调整
    if (maxHeight > self.frame.size.height) {
        
        self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, maxHeight);
    }
    
    //调整好整体视图后，再调整一次按钮组的位置，把其位置倒过来计算，从视图的底线向上计算，这样可以保正：在视图高度超过最低元素过多时，self的美观度
    CGRect frame = _buttonsContainer.frame;
    _buttonsContainer.frame = CGRectMake(frame.origin.x, self.frame.size.height - gap * 2 - frame.size.height, frame.size.width, frame.size.height);
}

// 组装按钮到按钮容器中
// 如果_otherButtons.count + _cancelButton = 2，就是一行放2个按钮；如果!= 2，就是一行一个按钮
- (void)assembleButtonsIntoContainerView
{
    float gap = 10;
    float buttonHeight = 30;
    
    //如果其他按钮=1且_cancelButton!=nil，就是有两个按钮；如果其他按钮=2且_cancelButton==nil，就是有两个按钮
    if ((_otherButtons.count == 1 && _cancelButton != nil) || (_otherButtons.count == 2 && _cancelButton == nil)) {
        
        float x = gap;
        float width = _buttonsContainer.frame.size.width / 2 - gap * 2;
        
        if (_cancelButton) {  //cancelButton在左边
            
            _cancelButton.frame = CGRectMake(x, 0, width, buttonHeight);
            [_buttonsContainer addSubview:_cancelButton];
            
            x += _cancelButton.frame.size.width + gap * 2;
        }

        //循环其他按钮，如果是2个，就能设定2个的frame；如果是一个，循环结束后就会遇上_cancelButton，并计算好x
        for (UIView* view in _otherButtons) {

            view.frame = CGRectMake(x, 0, width, buttonHeight);
            [_buttonsContainer addSubview:view];
            
            x += view.frame.size.width + gap * 2;    //x是加上上一个按钮的宽度和间隙计算出来的。如果只循环一次，那么就会被取消按钮用上
        }
    }
    else {
    
        //所有按钮数!=2
        float y = 0;
        for (UIButton* button in _otherButtons) {
            
            button.frame = CGRectMake(0, y, _buttonsContainer.frame.size.width, buttonHeight);
            [_buttonsContainer addSubview:button];
            
            y += buttonHeight + 5;
        }
        
        //装入cancel按钮
        if (_cancelButton) {
            
            _cancelButton.frame = CGRectMake(0, y + 5, _buttonsContainer.frame.size.width, buttonHeight);
            [_buttonsContainer addSubview:_cancelButton];
        }
    }
    
    //重新绘制frame
    if (_buttonsContainer.subviews.count > 0) {
        
        UIView* button = (UIView *)_buttonsContainer.subviews[_buttonsContainer.subviews.count - 1];
        float height = button.frame.origin.y + button.frame.size.height;  //通过最后一个子元素来获取高度
        _buttonsContainer.frame = CGRectMake(_buttonsContainer.frame.origin.x, _buttonsContainer.frame.origin.y, _buttonsContainer.frame.size.width, height);
    }
    
    //这样就得到了一个重新根据_otherButtons和_cancelButton实例，绘制的_buttonsContainer
}

@end



